package com.li.commons.util;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Calendar;

import javax.imageio.ImageIO;

import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ImageUtils {

	private static Logger logger = LoggerFactory.getLogger(ImageUtils.class);

	// GraphicMagic执行路径
	private static final String GMLOCAL = "/usr/local/bin/gm";
	//private static final String GMLOCAL = "D:\\Program Files\\GraphicsMagick\\gm.exe";
	

	public static String getImgUrlByTimeMillis(String platform) {
		String md5 = MD5.compute(String.valueOf(Calendar.getInstance().getTimeInMillis()));
		String imtUrl = String.format(platform, md5.substring(0, 2), md5.substring(2, 4), md5.substring(4, 6), md5);
		return imtUrl;
	}

	public static String getUserHeader(String workerNo) {
		return "/"+workerNo + ".jpg";
	}

	public static String getOrderFCodePicture(String fCode) {
		return "/order/f/order_f_" + fCode + ".jpg";
	}

	public static String getImgUrl(String platform, Integer id) {
		String md5 = MD5.compute(id.toString());
		String userImg = String.format(platform, md5.substring(0, 2), md5.substring(2, 4), md5.substring(4, 6), md5);
		return userImg;
	}

	public static String getWidthHeight(InputStream inputStream) {
		BufferedImage bufferedImage;
		try {
			bufferedImage = ImageIO.read(inputStream);
			int width = bufferedImage.getWidth();
			int height = bufferedImage.getHeight();
			return width + "x" + height;
		} catch (IOException e) {
			e.printStackTrace();
		}
		return "";
	}

	/**
	 * 压缩图片，不变形
	 * 
	 * @param filePath
	 *            源文件路径
	 * @param toPath
	 *            缩略图路径
	 * @param width
	 *            设定宽
	 * @param height
	 *            设定长
	 */
	public static int changeSize(String filePath, String toPath, int width, int height) {
		int r = -1;
		try {
			Process process = Runtime.getRuntime()
					.exec(GMLOCAL + " convert " + filePath + " -resize " + width + "x" + height + " " + toPath);
			// gm convert input.jpg -thumbnail '100x100!' output_2.jpg 会变形
			r = process.waitFor();
			if (r == 0) {
				File resultFile = new File(toPath + ".0");
				if (resultFile.exists()) {
					resultFile.renameTo(new File(toPath));
					if (resultFile.getParent() != null) {
						if (new File(resultFile.getParent()).isDirectory()) {
							for (File file : new File(resultFile.getParent()).listFiles()) {
								if (file.getPath().startsWith(toPath + ".")) {
									file.delete();
								}
							}
						}
					}
				}
			} else {
				logger.error("CHANGE SIZE ERROR [-filepath:" + filePath + " -toPath:" + toPath + "]");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return r;
	}

	/**
	 * 与changeSize方法功能一致，主要解决某些情况下远程图片压缩的错误
	 * 
	 * @param path
	 * @param toPath
	 * @param width
	 * @param height
	 * @return
	 */
	public static int changeRemoteImgSize(String path, String toPath, int width, int height) {
		int r = 0;
		String dir = toPath.substring(0, toPath.lastIndexOf("/"));
		String tmpFilePath = dir + "/" + System.currentTimeMillis() + ".jpg";
		FileOutputStream fos = null;
		InputStream is = null;
		try {
			URL url = new URL(path);
			HttpURLConnection imgConnection = (HttpURLConnection) url.openConnection();
			File file = new File(tmpFilePath);
			fos = new FileOutputStream(file);
			is = imgConnection.getInputStream();
			int n = 1024;
			int len = 0;
			byte buffer[] = new byte[n]; // 读取输入流 #
			while (((len = is.read(buffer, 0, n)) != -1)) {
				fos.write(buffer, 0, len);
			}
			r = changeSize(file.getAbsolutePath(), toPath, width, height);
			file.delete();
		} catch (MalformedURLException e) {
			e.printStackTrace(); // To change body of catch statement use File |
									// Settings | File Templates.
		} catch (IOException e) {
			e.printStackTrace(); // To change body of catch statement use File |
									// Settings | File Templates.
		} finally {
			try {
				if (fos != null) {
					fos.close();
				}
				if (is != null) {
					is.close();
				}
			} catch (IOException e) {
				e.printStackTrace(); // To change body of catch statement use
										// File | Settings | File Templates.
			}
		}

		return r;
	}

	/**
	 * 总动缩放返回
	 * 
	 * @param source
	 * @param targetW
	 * @param targetH
	 * @return
	 * @throws IOException
	 */
	public static Integer[] autoResize(String url, int targetW, int targetH) throws IOException {
		BufferedImage source = ImageIO.read(new URL(url));
		return autoResize(source, targetW, targetH);
	}

	public static Integer[] autoResize(File file, int targetW, int targetH) throws IOException {
		BufferedImage source = ImageIO.read(file);
		return autoResize(source, targetW, targetH);
	}

	public static Integer[] autoResize(BufferedImage source, int targetW, int targetH) {
		// targetW，targetH分别表示目标长和宽
		double sx = (double) targetW / source.getWidth();
		double sy = (double) targetH / source.getHeight();
		// 这里想实现在targetW，targetH范围内实现等比缩放。
		if (sx > sy) {
			sx = sy;
			targetW = (int) (sx * source.getWidth());
		} else {
			sy = sx;
			targetH = (int) (sy * source.getHeight());
		}
		Integer[] i = new Integer[] { targetW, targetH };

		return i;
	}

	/**
	 * 水印(图片logo)
	 * 
	 * @param filePath
	 *            源文件路径
	 * @param toImg
	 *            修改图路径
	 * @param logoPath
	 *            logo图路径
	 * @throws MagickException
	 */
	public static void addLogoImg(String filePath, String toImg, String logoPath) {
		try {
			Process process = Runtime.getRuntime().exec(
					GMLOCAL + " -composite -gravity NorthWest -dissolve 50 " + logoPath + " " + filePath + " " + toImg);
			process.waitFor();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 切图 (从中间切)
	 * 
	 * @param imgPath
	 *            源图路径
	 * @param toPath
	 *            修改图路径
	 * @param width
	 *            宽度
	 * @param height
	 *            高度
	 * @throws MagickException
	 */
	public static void cutImg(String imgPath, String toPath, int width, int height) {
		try {
			Process process = Runtime.getRuntime().exec(GMLOCAL + " convert " + imgPath + "  -gravity center -extent "
					+ width + "x" + height + " " + toPath);
			process.waitFor();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static String getImgFileLength(InputStream inputStream) {
		try {
			return IOUtils.toByteArray(inputStream).length / 1024 + "";
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				inputStream.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return "";
	}

	/**
	 * 压缩图片
	 * 
	 * @param headImg
	 *            图片文件
	 * @param maxPx
	 *            最大尺寸
	 * @author zhaochengju
	 * @throws IOException
	 */
	public static BufferedImage cutImage(BufferedImage headImg, int maxPx) throws IOException {
		int width = maxPx;
		int height = maxPx;
		if (headImg.getWidth() > headImg.getHeight()) {
			// 宽图片
			height = (int) (headImg.getHeight() * width / headImg.getWidth());
		} else if (headImg.getWidth() < headImg.getHeight()) {
			// 长图片
			width = (int) (headImg.getWidth() * height / headImg.getHeight());
		} else {
			width = headImg.getWidth();
			height = headImg.getHeight();
		}
		// 缩放图片
		Image img = headImg.getScaledInstance(width, height, Image.SCALE_SMOOTH);
		headImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
		Graphics g = headImg.createGraphics();
		g.drawImage(img, 0, 0, null);
		g.dispose();
		return headImg;
	}

}
